home *** CD-ROM | disk | FTP | other *** search
- ;/* rawkey.c - Execute me to compile me with SAS C 5.10
- LC -b1 -cfistq -v -y -j73 rawkey.c
- Blink FROM LIB:c.o,rawkey.o TO rawkey LIBRARY LIB:LC.lib,LIB:Amiga.lib
- quit
- */
-
- /*
- Copyright (c) 1992 Commodore-Amiga, Inc.
-
- This example is provided in electronic form by Commodore-Amiga, Inc. for
- use with the "Amiga ROM Kernel Reference Manual: Libraries", 3rd Edition,
- published by Addison-Wesley (ISBN 0-201-56774-1).
-
- The "Amiga ROM Kernel Reference Manual: Libraries" contains additional
- information on the correct usage of the techniques and operating system
- functions presented in these examples. The source and executable code
- of these examples may only be distributed in free electronic form, via
- bulletin board or as part of a fully non-commercial and freely
- redistributable diskette. Both the source and executable code (including
- comments) must be included, without modification, in any copy. This
- example may not be published in printed form or distributed with any
- commercial product. However, the programming techniques and support
- routines set forth in these examples may be used in the development
- of original executable software products for Commodore Amiga computers.
-
- All other rights reserved.
-
- This example is provided "as-is" and is subject to change; no
- warranties are made. All use is at your own risk. No liability or
- responsibility is assumed.
- */
-
- /*
- ** rawkey.c - How to correctly convert from RAWKEY to keymapped ASCII
- */
- #define INTUI_V36_NAMES_ONLY
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <devices/inputevent.h>
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/console_protos.h>
- #include <stdio.h>
-
- #ifdef LATTICE
- int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */
- int chkabort(void) { return(0); } /* really */
- #endif
-
- /* our function prototypes */
- LONG deadKeyConvert(struct IntuiMessage *msg, UBYTE *kbuffer,
- LONG kbsize, struct KeyMap *kmap, struct InputEvent *ievent);
- VOID print_qualifiers(ULONG qual);
- BOOL doKeys(struct IntuiMessage *msg, struct InputEvent *ievent,
- UBYTE **buffer, ULONG *bufsize);
- VOID process_window(struct Window *win, struct InputEvent *ievent,
- UBYTE **buffer, ULONG *bufsize);
-
- /* A buffer is created for RawKeyConvert() to put its output. BUFSIZE is the size of
- ** the buffer in bytes. NOTE that this program starts out with a buffer size of 2.
- ** This is only to show how the buffer is automatically increased in size by this
- ** example! In an application, start with a much larger buffer and you will probably
- ** never have to increase its size. 128 bytes or so should do the trick, but always
- ** be able to change the size if required.
- */
- #define BUFSIZE (2)
-
- struct Library *IntuitionBase, *ConsoleDevice;
-
- /* main() - set-up everything used by program. */
- VOID main(int argc, char **argv)
- {
- struct Window *win;
- struct IOStdReq ioreq;
- struct InputEvent *ievent;
- UBYTE *buffer;
- ULONG bufsize = BUFSIZE;
-
- if(IntuitionBase = OpenLibrary("intuition.library",37)) {
- /* Open the console device just to do keymapping. (unit -1 means any unit) */
- if (0 == OpenDevice("console.device",-1,(struct IORequest *)&ioreq,0)) {
- ConsoleDevice = (struct Library *)ioreq.io_Device;
-
- /* Allocate the initial character buffer used by deadKeyConvert() and RawKeyConvert()
- ** for returning translated characters. If the characters generated by these routines
- ** cannot fit into the buffer, the application must pass a larger buffer. This is
- ** done in this code by freeing the old buffer and allocating a new one.
- */
- if (buffer = AllocMem(bufsize,MEMF_CLEAR)) {
- if (ievent = AllocMem(sizeof(struct InputEvent),MEMF_CLEAR)) {
- if (win = OpenWindowTags(NULL,
- WA_Width, 300,
- WA_Height, 50,
- WA_Flags, WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_ACTIVATE,
- WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
- WA_Title, "Raw Key Example",
- TAG_END)) {
- printf("Press keyboard keys to see ASCII conversion from rawkey\n");
- printf("Unprintable characters will be shown as %c\n\n",0x7f);
- process_window(win,ievent,&buffer,&bufsize);
- CloseWindow(win);
- }
- FreeMem(ievent,sizeof(struct InputEvent));
- }
- /* Buffer can be freed elsewhere in the program so test first. */
- if (buffer != NULL)
- FreeMem(buffer,bufsize);
- }
- CloseDevice((struct IORequest *)&ioreq);
- }
- CloseLibrary(IntuitionBase);
- }
- }
-
- /* Convert RAWKEYs into VANILLAKEYs, also shows special keys like HELP, Cursor Keys,
- ** FKeys, etc. It returns:
- ** -2 if not a RAWKEY event.
- ** -1 if not enough room in the buffer, try again with a bigger buffer.
- ** otherwise, returns the number of characters placed in the buffer.
- */
- LONG deadKeyConvert(struct IntuiMessage *msg, UBYTE *kbuffer,
- LONG kbsize, struct KeyMap *kmap, struct InputEvent *ievent)
- {
- if (msg->Class != IDCMP_RAWKEY) return(-2);
- ievent->ie_Class = IECLASS_RAWKEY;
- ievent->ie_Code = msg->Code;
- ievent->ie_Qualifier = msg->Qualifier;
- ievent->ie_position.ie_addr = *((APTR*)msg->IAddress);
-
- return(RawKeyConvert(ievent,kbuffer,kbsize,kmap));
- }
-
- /* print_qualifiers() - print out the values found in the qualifier bits of
- ** the message. This will print out all of the qualifier bits set.
- */
- VOID print_qualifiers(ULONG qual)
- {
- printf("Qual:");
- if (qual & IEQUALIFIER_LSHIFT) printf("LShft,");
- if (qual & IEQUALIFIER_RSHIFT) printf("RShft,");
- if (qual & IEQUALIFIER_CAPSLOCK) printf("CapLok,");
- if (qual & IEQUALIFIER_CONTROL) printf("Ctrl,");
- if (qual & IEQUALIFIER_LALT) printf("LAlt,");
- if (qual & IEQUALIFIER_RALT) printf("RAlt,");
- if (qual & IEQUALIFIER_LCOMMAND) printf("LCmd,");
- if (qual & IEQUALIFIER_RCOMMAND) printf("RCmd,");
- if (qual & IEQUALIFIER_NUMERICPAD) printf("NumPad,");
- if (qual & IEQUALIFIER_REPEAT) printf("Rpt,");
- if (qual & IEQUALIFIER_INTERRUPT) printf("Intrpt,");
- if (qual & IEQUALIFIER_MULTIBROADCAST) printf("Multi Broadcast,");
- if (qual & IEQUALIFIER_MIDBUTTON) printf("MidBtn,");
- if (qual & IEQUALIFIER_RBUTTON) printf("RBtn,");
- if (qual & IEQUALIFIER_LEFTBUTTON) printf("LBtn,");
- if (qual & IEQUALIFIER_RELATIVEMOUSE) printf("RelMouse,");
- }
-
- /* doKeys() - Show what keys were pressed. */
- BOOL doKeys(struct IntuiMessage *msg, struct InputEvent *ievent,
- UBYTE **buffer, ULONG *bufsize)
- {
- USHORT char_pos;
- USHORT numchars;
- BOOL ret_code = TRUE;
- UBYTE realc, c;
-
- /* deadKeyConvert() returns -1 if there was not enough space in the buffer to
- ** convert the string. Here, the routine increases the size of the buffer on the
- ** fly...Set the return code to FALSE on failure.
- */
- numchars = deadKeyConvert(msg, *buffer, *bufsize - 1, NULL, ievent);
- while ((numchars == -1) && (*buffer != NULL)) {
- /* conversion failed, buffer too small. try to double the size of the buffer. */
- FreeMem(*buffer, *bufsize);
- *bufsize = *bufsize << 1;
- printf("Increasing buffer size to %d\n", *bufsize);
-
- if (NULL == (*buffer = AllocMem(*bufsize, MEMF_CLEAR))) ret_code = FALSE;
- else numchars = deadKeyConvert(msg, *buffer, *bufsize - 1, NULL, ievent);
- }
-
- /* numchars contains the number of characters placed within the buffer. Key up events and */
- /* key sequences that do not generate any data for the program (like deadkeys) will return */
- /* zero. Special keys (like HELP, the cursor keys, FKeys, etc.) return multiple characters */
- /* that have to then be parsed by the application. Allocation failed above if buffer is NULL*/
- if (*buffer != NULL) {
- /* if high bit set, then this is a key up otherwise this is a key down */
- if (msg->Code & 0x80)
- printf("Key Up: ");
- else
- printf("Key Down: ");
-
- print_qualifiers(msg->Qualifier);
- printf(" rawkey #%d maps to %d ASCII character(s)\n", 0x7F & msg->Code, numchars);
- for (char_pos = 0; char_pos < numchars; char_pos++) {
- realc = c = (*buffer)[char_pos];
- if ((c <= 0x1F)||((c >= 0x80)&&(c < 0xa0)))
- c = 0x7f;
- printf(" %3d ($%02x) = %c\n", realc, realc, c);
- }
- }
- return(ret_code);
- }
-
- /* process_window() - simple event loop. Note that the message is not replied
- ** to until the end of the loop so that it may be used in the doKeys() call.
- */
- VOID process_window(struct Window *win, struct InputEvent *ievent,
- UBYTE **buffer, ULONG *bufsize)
- {
- struct IntuiMessage *msg;
- BOOL done;
-
- done = FALSE;
- while (done == FALSE) {
- Wait((1L<<win->UserPort->mp_SigBit));
- while ((done == FALSE) && (msg = (struct IntuiMessage *)GetMsg(win->UserPort))) {
- switch (msg->Class) { /* handle our events */
- case IDCMP_CLOSEWINDOW:
- done = TRUE;
- break;
- case IDCMP_RAWKEY:
- if (FALSE == doKeys(msg,ievent,buffer,bufsize))
- done = TRUE;
- break;
- }
- ReplyMsg((struct Message *)msg);
- }
- }
- }
-